package com.example.edu.config;

import com.example.edu.domain.dto.DependencyDTO;
import org.hibernate.validator.HibernateValidator;
import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator;
import org.hibernate.validator.resourceloading.AggregateResourceBundleLocator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * @author yanzhao
 * @date 2022/1/11 17:26
 * @since 1.0.0
 */
@Configuration
public class ValidatorConfig {

    private static final Logger LOGGER = LoggerFactory.getLogger(ValidatorConfig.class);

    public static final String MESSAGES = "messages";
    public static final String MESSAGES_PATTERN = "messages/*.properties";

    /**
     * 配置验证器
     *
     * @return validator
     */
    @Bean
    public Validator validator() {
        List<String> filenames = new ArrayList<>();
        try {
            Resource[] resources = new PathMatchingResourcePatternResolver()
                    .getResources(MESSAGES_PATTERN);
            if (resources != null && resources.length > 0) {
                for (Resource resource : resources) {
                    String filename = resource.getFilename();
                    filenames.add(MESSAGES + "/" + resource.getFilename().substring(0, filename.indexOf(".")));
                }
            }
        } catch (Exception e) {
            LOGGER.warn("not found any message file");
        }
        // Validation.byDefaultProvider()没有failFast(true)快速失败
        ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
                .configure()
                // 添加自定义的校验文件
                // PlatformResourceBundleLocator单个文件
                // AggregateResourceBundleLocator多个文件
                // new ResourceBundleMessageInterpolator(new PlatformResourceBundleLocator("message"))
                .messageInterpolator(new ResourceBundleMessageInterpolator(new AggregateResourceBundleLocator(filenames)))
                // 快速失败模式
                .failFast(true)
                .buildValidatorFactory();
        return validatorFactory.getValidator();
    }

    /**
     * 设置方法参数验证器
     */
    @Bean
    public MethodValidationPostProcessor methodValidationPostProcessor() {
        MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor();
        // 设置validator模式为快速失败返回
        postProcessor.setValidator(validator());
        return postProcessor;
    }

    public static void main(String[] args) {
        final ValidatorConfig validatorConfig = new ValidatorConfig();
        final Validator validator = validatorConfig.validator();
        final Set<ConstraintViolation<DependencyDTO>> validate = validator.validate(new DependencyDTO());
        validate.stream().forEach(x -> {
            System.out.println(x.getMessage());
        });
    }
}
